import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type AxiosError, type CancelTokenSource } from 'axios'
import type { BaseResponse } from '../types/request'
// import { ElMessage } from 'element-plus'
// import router from '@/router'

/* 1. 环境变量自动切换 baseURL */
const service: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_BASE_URL as string,
    timeout: 30000
})

/* 2. 请求拦截：统一携带 Token */
service.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('access_token')
        if (token && config.headers) {
            config.headers.Authorization = `Bearer ${token}`
        }
        return config
    },
    (error: AxiosError) => Promise.reject(error)
)

/* 3. 响应拦截：统一错误处理 & 退出登录 */
service.interceptors.response.use(
    (res: AxiosResponse<BaseResponse>) => {
        const { code, msg, data } = res.data
        if (code === 0) return data
        console.error(msg || '系统异常')
        return Promise.reject(new Error(msg))
    },
    (error: AxiosError<BaseResponse>) => {
        // 处理取消请求的错误
        if (axios.isCancel(error)) {
            console.log('请求已取消:', error.message)
            return Promise.reject(error)
        }
        
        const status = error.response?.status
        if (status === 401) {
            localStorage.clear()
            location.href = '/'
            // router.replace('/login')
        } else {
            console.error(error.response?.data?.msg || '网络异常')
        }
        return Promise.reject(error)
    }
)

/* 4. 核心泛型函数：保证类型安全 */
export function request<T = any>(config: AxiosRequestConfig): Promise<T> {
    return service.request<any, T>(config)
}

/* 5. 创建取消令牌 */
export function createCancelToken(): CancelTokenSource {
    return axios.CancelToken.source()
}

/* 6. 批量请求处理函数 */
export function all<T extends any[]>(promises: Array<Promise<T[number]>>): Promise<T> {
    return Promise.all(promises) as Promise<T>
}

/* 7. 处理批量请求的响应结果 */
export function spread<T extends any[], R>(callback: (...args: T) => R) {
    return (arr: T) => callback(...arr)
}

/* 8. 快捷方法 */
export const http = {
    get<T = any>(url: string, params?: object, config?: AxiosRequestConfig) {
        return request<T>({ method: 'GET', url, params, ...config })
    },
    post<T = any>(url: string, data?: object, config?: AxiosRequestConfig) {
        return request<T>({ method: 'POST', url, data, ...config })
    },
    put<T = any>(url: string, data?: object, config?: AxiosRequestConfig) {
        return request<T>({ method: 'PUT', url, data, ...config })
    },
    delete<T = any>(url: string, config?: AxiosRequestConfig) {
        return request<T>({ method: 'DELETE', url, ...config })
    },
    download(url: string, filename?: string, config?: AxiosRequestConfig) {
        return request<AxiosResponse<Blob>>({ method: 'GET', url, responseType: 'blob', ...config })
            .then(response => {
                const contentDisposition = response.headers['content-disposition']
                let finalFilename = filename || 'download'
                if (contentDisposition) {
                    const matches = contentDisposition.match(/filename=([^;]+)/)
                    if (matches && matches[1]) {
                        finalFilename = decodeURIComponent(matches[1].trim())
                    }
                }
                const downloadUrl = window.URL.createObjectURL(response.data)
                const a = document.createElement('a')
                a.href = downloadUrl
                a.download = finalFilename
                document.body.appendChild(a)
                a.click()
                a.remove()
                window.URL.revokeObjectURL(downloadUrl)
            })
            .catch((error) => {
                if (!axios.isCancel(error)) {
                    console.error('下载失败', error)
                }
                throw error
            })
    },
    upload<T = any>(url: string, file: File, data?: Record<string, any>, config?: AxiosRequestConfig) {
        const formData = new FormData()
        formData.append('file', file)
        if (data) {
            for (const key in data) {
                formData.append(key, data[key])
            }
        }
        return request<T>({ method: 'POST', url, data: formData, ...config })
    },
    // 批量请求方法
    all<T extends any[]>(promises: Array<Promise<T[number]>>): Promise<T> {
        return all(promises)
    },
    // 批量处理响应结果
    spread<T extends any[], R>(callback: (...args: T) => R) {
        return spread(callback)
    },
    // 创建取消令牌
    createCancelToken() {
        return createCancelToken()
    }
}

export default service